import React, { FC, useState, useEffect, useCallback, ReactNode, useMemo } from 'react';
import { Tag, Input, Badge, Space, Select, Switch } from 'antd';
import { useLocation, useParams } from 'react-router-dom';
import { isArray, isNil, isEmpty } from 'lodash';
import { ColumnType } from 'antd/lib/table';

import { Header, Content } from '@components/Page';
import Icons from '@components/Icons';
import Button from '@components/Button';
import Table from '@components/Table';
import CollapseQueryBar from '@components/CollapseQueryBar';
import { useForm } from '@components/Form';
import EditDrawerForm from '@components/EditDrawerForm';

import { getDictionaryListApi } from '@services/service';
import { Status, WhetherStatus, MethodType, MethodTypeColor } from '@enumTypes/enumTypes';
import {
  COMMON_PAGINATION,
  COMMON_REQUIRE_RULE,
  COMMON_SELECT_FIELDSNAMES,
  COMPLETELY_FILL_STYLE,
  VALIDATE_COMMON_CODE,
  VALIDATE_COMMON_PATHNAME
} from '@utils/config';
import request from '@utils/request';
import {
  generateCommonSelect,
  useResetFormOnCloseModal,
  generateCommonDeleteModal,
  setOtherTypeValue
} from '@utils/renderer';
import { getPropValueByValue, getFormValues } from '@utils/util';
import notification from '@utils/notification';

interface SubfunctionProps {}

const Subfunction: FC<SubfunctionProps> = () => {
  const [loading, setLoading] = useState<boolean>(false);
  const [saveLoading, setSaveLoading] = useState<boolean>(false);

  // 字典数据
  const [yesOrNoList, setYesOrNoList] = useState<any[]>([]);
  const [statusList, setStatusList] = useState<any[]>([]);
  const [methodTypeList, setMethodTypeList] = useState<any[]>([]);

  const [tableData, setTableData] = useState<any[]>([]);
  const [pagination, setPagination] = useState<any>(COMMON_PAGINATION);
  const [selectedRowKeys, setSelectedRowKeys] = useState<any[]>([]);
  const [selectedRows, setSelectedRows] = useState<any[]>([]);

  const [operationType, setOperationType] = useState<string>('');
  const [openFlag, setOpenFlag] = useState<boolean>(false);

  const { state } = useLocation();
  const urlParams = useParams();
  const { icon, status, name }: any = state || {};

  const [queryForm] = useForm(); // 查询表单
  const [editForm] = useForm(); // 编辑表单

  useResetFormOnCloseModal({ form: editForm, openFlag });

  /** 查询设置字典数据 */
  const handleQueryDictionaryList = useCallback(() => {
    getDictionaryListApi(['RB_YES_NO', 'RB_STATUS', 'RB_REQUEST_METHOD']).then((res: any) => {
      if (isArray(res)) {
        const [yesOrNoList = [], statusList = [], methodTypeList = []] = res || [];
        setYesOrNoList(yesOrNoList);
        setStatusList(statusList);
        setMethodTypeList(methodTypeList);
        console.log(methodTypeList);
      }
    });
  }, []);

  /** 查询表格数据 */
  const handleQueryData = useCallback((params?: any) => {
    setLoading(true);
    request({
      url: '/system/route',
      method: 'GET',
      params
    })
      .then((res: any) => {
        if (res) {
          const { current, size, total, records = [] } = res;
          // 设置分页数据
          setPagination({ ...COMMON_PAGINATION, current, size: size, total });
          setTableData(records);
          // 查询重置勾选
          setSelectedRowKeys([]);
          setSelectedRows([]);
        }
      })
      .finally(() => {
        setLoading(false);
      });
  }, []);

  const callBackHandleQueryData = useCallback(
    (params?: any) => handleQueryData({ ...COMMON_PAGINATION, menuId: urlParams.id, ...params }),
    [handleQueryData, urlParams.id]
  );

  useEffect(() => {
    handleQueryDictionaryList();
    callBackHandleQueryData();
  }, [callBackHandleQueryData, handleQueryDictionaryList]);

  /** 分页切换重新查询表格数据 */
  const handleTableChange = useCallback(
    async ({ current, size }: any) => {
      const fields = await getFormValues(queryForm);
      callBackHandleQueryData({ ...fields, current, size });
    },
    [callBackHandleQueryData, queryForm]
  );

  /** 表单查询 */
  const handleSearch = useCallback(
    (values: any) => {
      callBackHandleQueryData(values);
    },
    [callBackHandleQueryData]
  );

  /** 打开 新增|编辑 抽屉 */
  const handleOpenEditDrawer = useCallback(
    (type: string) => {
      // 设置操作类型
      setOperationType(type);

      if (type === 'update') {
        // 设置抽屉表单数据
        editForm.setFieldsValue(selectedRows[0] || {});
      }

      // 打开抽屉
      setOpenFlag(true);
    },
    [editForm, selectedRows]
  );

  /** 保存 */
  const handleSave = useCallback(async () => {
    // 表单未修改
    if (!editForm.isFieldsTouched()) {
      // 关闭抽屉
      setOpenFlag(false);
      return;
    }

    // 校验获取值
    const fields = await editForm.validateFields();

    // 校验通过
    if (fields) {
      setSaveLoading(true);
      request({
        url: '/system/route',
        method: operationType === 'update' ? 'PUT' : 'POST',
        data: { menuId: urlParams.id, ...selectedRows[0], ...fields }
      })
        .then(async (res: any) => {
          if (res) {
            notification.success();
            // 关闭抽屉
            setOpenFlag(false);
            const params = await getFormValues(queryForm);
            const { current, size } = pagination;
            // 查询最新数据
            callBackHandleQueryData({ ...params, current, size });
          }
        })
        .finally(() => {
          setSaveLoading(false);
        });
    }
  }, [
    callBackHandleQueryData,
    editForm,
    operationType,
    pagination,
    queryForm,
    selectedRows,
    urlParams.id
  ]);

  /** 删除 */
  const handleDelete = useCallback(() => {
    if (isEmpty(selectedRowKeys)) return;

    generateCommonDeleteModal({
      title: '是否确定删除这些 子功能 ?',
      onOk() {
        setLoading(true);
        request({
          url: '/system/route',
          method: 'DELETE',
          data: selectedRowKeys
        })
          .then(async (res: any) => {
            if (res) {
              notification.success();
              const params = await getFormValues(queryForm);
              // 查询最新数据
              callBackHandleQueryData(params);
            }
          })
          .finally(() => {
            setLoading(false);
          });
      }
    });
  }, [callBackHandleQueryData, queryForm, selectedRowKeys]);

  /** 头渲染 */
  const renderTitle = useCallback((): ReactNode => {
    return (
      <div style={{ display: 'flex', alignItems: 'center' }}>
        <div style={{ marginRight: 8 }}>子功能设置</div>
        {!!state && (
          <Tag icon={<Icons type={icon} />} color={status === Status.enable ? 'green' : 'red'}>
            {name}
          </Tag>
        )}
      </div>
    );
  }, [icon, name, state, status]);

  /** 查询条配置列表 */
  const queryFromItems = useMemo(
    () => [
      {
        name: 'name',
        label: '功能名称',
        children: <Input />
      },
      {
        name: 'code',
        label: '功能编码',
        children: <Input />
      },
      {
        name: 'methodType',
        label: '请求类型',
        children: generateCommonSelect(methodTypeList)
      },
      {
        name: 'online',
        label: '是否在线',
        children: generateCommonSelect(yesOrNoList)
      },
      {
        name: 'status',
        label: '状态',
        children: generateCommonSelect(statusList)
      }
    ],
    [methodTypeList, statusList, yesOrNoList]
  );

  /** 编辑表单配置列表 */
  const editFormItems = useMemo(
    () => [
      {
        name: 'name',
        label: '功能名称',
        rules: [COMMON_REQUIRE_RULE],
        children: <Input />
      },
      {
        name: 'code',
        label: '功能编码',
        rules: [COMMON_REQUIRE_RULE, VALIDATE_COMMON_CODE],
        tooltip: VALIDATE_COMMON_CODE.message,
        children: <Input disabled={operationType === 'update'} allowClear />
      },
      {
        name: 'pattern',
        label: '映射路径',
        rules: [COMMON_REQUIRE_RULE, VALIDATE_COMMON_PATHNAME],
        tooltip: VALIDATE_COMMON_PATHNAME.message,
        children: <Input allowClear />
      },
      {
        name: 'methodType',
        label: '请求类型',
        rules: [COMMON_REQUIRE_RULE],
        tooltip: VALIDATE_COMMON_PATHNAME.message,
        children: (
          <Select
            style={COMPLETELY_FILL_STYLE}
            fieldNames={COMMON_SELECT_FIELDSNAMES}
            options={methodTypeList}
          />
        )
      },
      {
        name: 'online',
        label: '是否在线',
        valuePropName: 'checked',
        rules: [COMMON_REQUIRE_RULE],
        ...setOtherTypeValue(1, 0),
        children: <Switch checkedChildren="在线" unCheckedChildren="下线" />
      },
      {
        name: 'status',
        label: '状态',
        valuePropName: 'checked',
        rules: [COMMON_REQUIRE_RULE],
        ...setOtherTypeValue(1, 0),
        children: <Switch checkedChildren="启用" unCheckedChildren="禁用" />
      }
    ],
    [operationType, methodTypeList]
  );

  /** 表格列配置 */
  const columns: ColumnType<any>[] = useMemo(
    () => [
      {
        title: '功能名称',
        dataIndex: 'name',
        width: 180
      },
      {
        title: '功能编码',
        dataIndex: 'code',
        width: 280
      },
      {
        title: '映射路径',
        dataIndex: 'pattern'
      },
      {
        title: '请求类型',
        align: 'center',
        dataIndex: 'methodType',
        width: 100,
        render: (value: any) => {
          return (
            !isNil(value) && (
              <Tag
                color={
                  MethodTypeColor[
                    MethodType[
                      value as keyof typeof MethodType
                    ] as unknown as keyof typeof MethodTypeColor
                  ]
                }
              >
                {getPropValueByValue(value, methodTypeList)}
              </Tag>
            )
          );
        }
      },
      {
        title: '是否在线',
        align: 'center',
        dataIndex: 'online',
        width: 100,
        render: (value: any) => {
          return (
            !isNil(value) && (
              <Space>
                <Badge status={WhetherStatus.yes === value ? 'success' : 'error'} />
                {getPropValueByValue(value, yesOrNoList)}
              </Space>
            )
          );
        }
      },
      {
        title: '状态',
        align: 'center',
        dataIndex: 'status',
        width: 100,
        render: (value: any) => {
          return (
            !isNil(value) && (
              <Space>
                <Badge status={Status.enable === value ? 'success' : 'error'} />
                {getPropValueByValue(value, statusList)}
              </Space>
            )
          );
        }
      }
    ],
    [methodTypeList, statusList, yesOrNoList]
  );

  /** 勾选配置 */
  const rowSelection = {
    selectedRowKeys,
    onChange: (newSelectedRowKeys: React.Key[], newSelectedRows: any[]) => {
      setSelectedRowKeys(newSelectedRowKeys);
      setSelectedRows(newSelectedRows);
    }
  };

  return (
    <>
      <Header backPath="/menu" title={renderTitle()} />
      <Content loading={loading}>
        <CollapseQueryBar
          form={queryForm}
          queryFromItems={queryFromItems}
          handleSearch={handleSearch}
        />
        <div style={{ textAlign: 'right', marginBottom: 8 }}>
          <Space>
            <Button type="primary" onClick={() => handleOpenEditDrawer('create')}>
              新增
            </Button>
            <Button
              type="primary"
              disabled={selectedRows.length !== 1}
              onClick={() => handleOpenEditDrawer('update')}
            >
              修改
            </Button>
            <Button type="primary" danger disabled={!selectedRowKeys.length} onClick={handleDelete}>
              删除
            </Button>
          </Space>
        </div>
        <Table
          rowKey="id"
          columns={columns}
          dataSource={tableData}
          pagination={pagination}
          onChange={handleTableChange}
          rowSelection={rowSelection}
          sticky // 表头随页面滚动固定
        />
        {openFlag && (
          <EditDrawerForm
            title={operationType === 'update' ? '编辑' : '新增'}
            openFlag={openFlag}
            setOpenFlag={setOpenFlag}
            form={editForm}
            handleSave={handleSave}
            loading={saveLoading}
            formItems={editFormItems}
            initialValues={{
              online: 1,
              status: 1
            }}
          />
        )}
      </Content>
    </>
  );
};

export default Subfunction;
